﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Script.Serialization;
using ShopB2C.Entity;
using ShopB2C.Enums;
using ShopB2C.Helper;
using ShopB2C.Interfaces;
using ShopB2C.Parameters;
using ShopB2C.ViewModels;

namespace ShopB2C.Controllers.Brower {
    public partial class ProductController : BaseController {
        private const string _moduleKey = "Product";
        private const string _historyCook = "ShopB2C_History";
        private static IProductPreview _productPreView;
        private static IBrand _brand;
        private static IClassify _classify;
        private static IProductSearchKeys _psk;
        private static IOrder _orderAccess;

        public ProductController() {
            _productPreView = DataBaseExecuter.CreateClassByName<IProductPreview>("ProductPreView");
            _classify = DataBaseExecuter.CreateClassByName<IClassify>("ClassIfy");
            _brand = DataBaseExecuter.CreateClassByName<IBrand>("Brand");
            _psk = DataBaseExecuter.CreateClassByName<IProductSearchKeys>("ProductSearchKeys");
            _orderAccess = DataBaseExecuter.CreateClassByName<IOrder>("OrderAccess");
        }

        protected override void Initialize(RequestContext requestContext) {
            base.Initialize(requestContext);
            this.SiteMapPathAdd("首页", Url.Action("Index", "Home"));
            this.SiteMapPathAdd("所有商品", Url.Action("ProductList", new {
                productParams = new ProductParam().ToString()
            }));
            ViewData["ImageRoot"] = _imageRoot;
        }
        /// <summary>
        /// 商品列表
        /// </summary>
        public ActionResult ProductList([DefaultValue("(0)-(0)-1-0-1-1")]string productParams) {
            ProductParam pp = Methods.FormatProductParams(productParams);

            if (pp.Classify.Count == 1 && pp.Classify[0] == 0) {
                this.SiteMapPathEdit("所有商品", "所有商品");
            }

            int pageCount, rowsCount, classifyId = pp.Classify.Last();
            ProductViewModel viewModel = new ProductViewModel() {
                ImageRoot = _imageRoot,
                ProductParams = pp,
                SortDict = new Dictionary<string, string>(),
                ShowTypeDict = new Dictionary<ProductShowType, string>()
            };
            // 所有分类
            viewModel.ClassifyList = _classify.GetClassifyByModuleKey(_moduleKey);
            // 当前分类
            viewModel.Classify = _classify.GetClassifyById(classifyId)
                ?? new ClassifyEntity() { Childs = 0, Title = "所有分类" };
            // sitemappath
            List<ClassifyEntity> pathList =
                _classify.GetClassifyByModuleKeyAndPath(_moduleKey, pp.JoinClassify("-"));
            if (pathList != null) {
                List<int> cPathList = new List<int>() { 0 };
                foreach (ClassifyEntity ce in pathList) {
                    cPathList.Add(ce.ClassifyId);
                    ProductParam ppPath = pp.Clone();
                    ppPath.Classify = cPathList;
                    this.SiteMapPathAdd(ce.Title.Trim(), Url.Action("ProductList", new {
                        productParams = ppPath.ToString()
                    }));
                }
                this.SiteMapPathEdit(viewModel.Classify.Title, viewModel.Classify.Title);
            }

            string propertyVals = string.Empty;
            // 判断是否为最后一级分类,只有为最后一级分类时才显示属性
            if (viewModel.Classify.Childs < 1 && viewModel.Classify.ParentClassifyId != 0) {
                // 该分类有属性的时候获取到的属性
                List<ProductPropertyEntity> filter = _productPreView.PropertyFilter(classifyId);
                Dictionary<string, IEnumerable<ProductPropertyEntity>> filterGroupBy
                    = new Dictionary<string, IEnumerable<ProductPropertyEntity>>();
                var temp = filter.GroupBy(pe => pe.PropertyName, (key, list) => {
                    filterGroupBy.Add(key, list);
                    return 0;
                });
                foreach (var item in temp) { };
                viewModel.PropertyFilter = filterGroupBy;
                // 产生特性筛选
                if (viewModel.ProductParams.PropertyVal.Count != filterGroupBy.Keys.Count) {
                    viewModel.ProductParams.PropertyVal.Clear();
                    for (int i = 0; i < filterGroupBy.Keys.Count; i++) {
                        viewModel.ProductParams.PropertyVal.Add(0);
                    }
                    if (viewModel.ProductParams.PropertyVal.Count < 1) {
                        viewModel.ProductParams.PropertyVal.Add(0);
                    }
                }
                propertyVals = viewModel.ProductParams.JoinPropertyVal(",");
            }
            else {
                viewModel.ProductParams.PropertyVal.Clear();
                viewModel.ProductParams.PropertyVal.Add(0);
                viewModel.ChildClassify = _classify.GetClassifyByModuleKeyAndId(_moduleKey, classifyId);
            }
            // 分类下的所有产品
            viewModel.ProductList = _productPreView.Search(
                new ProductSearchCondition() {
                    PageSize = 16,
                    PageIndex = pp.PageIndex,
                    ClassifyId = classifyId,
                    Status = ProductSearchActionType.Sale,
                    SortIndex = pp.SortFieldName,
                    SortDescription = pp.SortDescription,
                    PropertyValIds = propertyVals,
                    IsActive = true
                }, out pageCount, out rowsCount);
            viewModel.RowsCount = rowsCount;
            // 分页
            ProductParam ppPager = pp.Clone();
            ppPager.PageIndex = 1234554321;
            viewModel.Pager = this.CreatePager(
                Url.Action("ProductList", new {
                    productParams = ppPager.ToString().Replace("1234554321", "{0}")
                }), pageCount, pp.PageIndex);
            // 构造 url
            this.CreateUrl(pp, viewModel);

            return View(viewModel);
        }
        /// <summary>
        /// 商品预览
        /// </summary>
        [HistoryAttriubte(_historyCook)]
        public ActionResult PreView([DefaultValue(0)]int productId) {

            ProductViewModel viewModel = new ProductViewModel() {
                ImageRoot = _imageRoot,
                ProductParams = new ProductParam()
            };
            ProductEntity productView = _productPreView.ProductView(productId, _user.Uid);

            if (productView == null) {
                return Content("没有找到相关商品信息!");
            }
            // 当前分类
            ClassifyEntity currentClass = _classify.GetClassifyById(productView.ClassId) ?? new ClassifyEntity() { Title = "所有分类" };
            viewModel.Classify = currentClass;
            // 当前分类的父分类，获取他的同辈分类
            viewModel.ParentClassify = _classify.GetClassifyById(currentClass.ParentClassifyId) ?? new ClassifyEntity() { Title = "所有分类" };
            //当前分类的的同辈分类
            viewModel.ChildClassify = _classify.GetClassifyByModuleKeyAndId(_moduleKey, currentClass.ParentClassifyId);
            // 分类参数
            List<int> classifyParams = new List<int>() { 0 };
            classifyParams.AddRange(
                currentClass.Path.Split('-').ToList().ConvertAll<int>(p => { return int.Parse(p); }));
            viewModel.ProductParams.Classify = classifyParams;
            // 同类品牌
            BrandEntity brand = _brand.GetBrandById(productView.BrandId) ?? new BrandEntity() { ClassifyId = -1 };
            viewModel.BrandList = _brand.GetBrandList(brand.ClassifyId, null) ?? new List<BrandEntity>();
            //产品信息
            viewModel.ProductView = productView;
            //所有分类
            viewModel.ClassifyList = _classify.GetClassifyByModuleKey(_moduleKey);
            // 属性列表
            viewModel.PropertyList = _productPreView.PropertyList(productId, null);
            // 图片列表
            viewModel.ImageList = _productPreView.GetImageList(productId);
            // 详细介绍
            viewModel.Details = _productPreView.GetDetails(productId);
            // 可选属性
            Dictionary<string, IEnumerable<ProductExtendEntity>> extendProperty = new Dictionary<string, IEnumerable<ProductExtendEntity>>();
            List<ProductExtendEntity> extendList = _productPreView.ProductExtendList(productId);
            var temp = extendList.GroupBy(i => i.ExtendKey, (key, list) => { extendProperty.Add(key, list); return 0; });
            foreach (var i in temp) ;
            viewModel.ExtendProperty = extendProperty;
            // sitemappath
            List<ClassifyEntity> pathList =
                _classify.GetClassifyByModuleKeyAndPath(_moduleKey,
                string.Format("{0}-{1}", currentClass.Path, currentClass.ClassifyId));
            if (pathList != null) {
                List<int> cPathList = new List<int>() { 0 };
                foreach (ClassifyEntity ce in pathList) {
                    cPathList.Add(ce.ClassifyId);
                    ProductParam ppPath = new ProductParam() {
                        Classify = cPathList
                    };
                    this.SiteMapPathAdd(ce.Title.Trim(), Url.Action("ProductList", new {
                        productParams = ppPath.ToString()
                    }));
                }
            }
            this.SiteMapPathAdd(productView.SubName);

            return View(viewModel);
        }
        /// <summary>
        /// 产品搜索
        /// </summary>
        public ActionResult Search(
            [DefaultValue("")]string key,
            [DefaultValue(0)]int classifyId,
            [DefaultValue(0)]int brandId,
            [DefaultValue(1)]int view,
            [DefaultValue(0)]int sortF,
            [DefaultValue(1)]int sortD,
            [DefaultValue("")]string price,
            [DefaultValue(1)]int pageIndex) {

            this.SiteMapPathEdit("所有商品", "商品搜索");

            int pageCount = 0, rowsCount = 0;
            decimal priceF = 0, priceT = 0;
            if (!string.IsNullOrEmpty(price)) {
                string[] prices = price.Split('-');
                if (prices.Length > 0) {
                    decimal.TryParse(prices[0], out priceF);
                    decimal.TryParse(prices[1], out priceT);
                }
            }
            ProductSearchCondition psc = new ProductSearchCondition() {
                Key = key,
                ClassifyId = classifyId,
                BrandId = brandId,
                ShowType = (ProductShowType)view,
                SortIndex = (ProductSortFieldNames)sortF,
                SortDescription = (SortDescriptions)sortD,
                PriceFrom = priceF,
                PriceTo = priceT,
                PageIndex = pageIndex,
                PageSize = 16
            };
            List<ProductEntity> productList = _productPreView.Search(psc, out pageCount, out rowsCount);
            // 更新搜索关键字
            if (productList.Count > 0) {
                _psk.ProductSearchKeysUpdateSearchNums(key);
            }
            object pager = this.CreatePager(Url.Action("Search", new {
                Key = key,
                ClassifyId = classifyId,
                BrandId = brandId,
                ShowType = (ProductShowType)view,
                SortIndex = (ProductSortFieldNames)sortF,
                SortDescription = (SortDescriptions)sortD,
                PriceFrom = priceF,
                PriceTo = priceT,
                PageIndex = "{0}"
            }), pageCount, pageIndex);

            List<ClassifyEntity> classifyList = new List<ClassifyEntity>();
            foreach (var item in productList.GroupBy(p => p.ClassId, (c, pl) => new {
                ClassifyId = c,
                ProductCount = pl.Count(),
                ClassifyName = pl.First().ClassifyName
            })) {
                classifyList.Add(new ClassifyEntity() {
                    ClassifyId = item.ClassifyId,
                    Title = item.ClassifyName,
                    Childs = item.ProductCount
                });
            }
            // 品牌
            List<BrandEntity> brandList = new List<BrandEntity>();
            foreach (var item in productList.GroupBy(p => p.BrandId, (b, pl) => new {
                BrandId = b,
                ProductCount = pl.Count(),
                BrandName = pl.First().BrandName
            }).Where(a => { return !string.IsNullOrEmpty(a.BrandName); })) {
                brandList.Add(new BrandEntity() {
                    BrandId = item.BrandId,
                    Sequence = item.ProductCount,
                    Name = item.BrandName
                });
            }
            if (brandList.Count < 1 && brandId > 0) {
                brandList.Add(_brand.GetBrandById(brandId));
            }

            ProductViewModel viewModel = new ProductViewModel() {
                ImageRoot = _imageRoot,
                Search = psc,
                RowsCount = rowsCount,
                ProductList = productList,
                ClassifyList = classifyList,
                BrandList = brandList,
                Pager = pager
            };

            return View(viewModel);
        }
        /// <summary>
        /// 部件调用
        /// </summary>
        public ActionResult ProductPart([DefaultValue(0)]int partId) {
            ProductPartEntity p = _productPreView.GetProductPart(partId, true);
            if (object.Equals(p, null))
                return new EmptyResult();
            p.ImageRoot = _imageRoot;
            return View(p);
        }
        /// <summary>
        /// 相关产品
        /// </summary>
        public ActionResult SameProduct([DefaultValue(0)]int productId, ProductPart moduleKey) {
            ProductPartEntity p = _productPreView.SameProduct(productId, moduleKey);
            if (object.Equals(p, null))
                return new EmptyResult();
            p.ImageRoot = _imageRoot;
            return Json(p, JsonRequestBehavior.AllowGet);
        }


        #region Methods

        private void CreateUrl(ProductParam pp, ProductViewModel viewModel) {
            // 排序 url
            ProductParam ppSaleDateTime = pp.Clone();
            ppSaleDateTime.SortFieldName = ProductSortFieldNames.SaleDateTime;
            ProductParam ppSaleCount = pp.Clone();
            ppSaleCount.SortFieldName = ProductSortFieldNames.SaleCount;
            ProductParam ppReplayCount = pp.Clone();
            ppReplayCount.SortFieldName = ProductSortFieldNames.ReplayCount;
            ProductParam ppPriceASC = pp.Clone();
            ppPriceASC.SortFieldName = ProductSortFieldNames.Price;
            ppPriceASC.SortDescription = SortDescriptions.ASC;
            ProductParam ppPriceDESC = pp.Clone();
            ppPriceDESC.SortFieldName = ProductSortFieldNames.Price;
            ppPriceDESC.SortDescription = SortDescriptions.DESC;
            viewModel.SortDict.Add("SaleDateTime",
                Url.Action("ProductList", new { productParams = ppSaleDateTime.ToString() }));
            viewModel.SortDict.Add("SaleCount",
                Url.Action("ProductList", new { productParams = ppSaleCount.ToString() }));
            viewModel.SortDict.Add("PriceASC",
                Url.Action("ProductList", new { productParams = ppPriceASC.ToString() }));
            viewModel.SortDict.Add("PriceDESC",
                Url.Action("ProductList", new { productParams = ppPriceDESC.ToString() }));
            viewModel.SortDict.Add("ReplayCount",
                Url.Action("ProductList", new { productParams = ppReplayCount.ToString() }));
            // 显示方式
            ProductParam ppShowTypeList = pp.Clone();
            ppShowTypeList.ShowType = ProductShowType.List;
            ProductParam ppShowTypeDetail = pp.Clone();
            ppShowTypeDetail.ShowType = ProductShowType.Detail;
            viewModel.ShowTypeDict.Add(ProductShowType.List,
                Url.Action("ProductList", new { productParams = ppShowTypeList.ToString() }));
            viewModel.ShowTypeDict.Add(ProductShowType.Detail,
                Url.Action("ProductList", new { productParams = ppShowTypeDetail.ToString() }));
        }

        #endregion

        #region AJAX

        /// <summary>
        /// 获取最近浏览的历史记录
        /// </summary>
        [HttpPost]
        public ActionResult ProductHistory() {
            string historyCookie = Request.Cookies[_historyCook] != null
                ? Request.Cookies[_historyCook].Value
                : string.Empty;
            string ids = string.Empty;
            try {
                JavaScriptSerializer json = new JavaScriptSerializer();
                Dictionary<string, DateTime> history = json.Deserialize<Dictionary<string, DateTime>>(historyCookie)
                    ?? new Dictionary<string, DateTime>();

                foreach (var i in history) {
                    ids += string.Format("{0},", i.Key);
                }
            }
            catch { }
            return View(_productPreView.GetProductByIds(ids.Trim(',')));
        }
        /// <summary>
        /// 清空浏览的历史记录
        /// </summary>
        [HttpPost]
        public ActionResult ClearHistory() {
            Response.Cookies.Add(new System.Web.HttpCookie(_historyCook) {
                Expires = DateTime.Now.AddDays(-1)
            });
            return View("ProductHistory", new List<ProductEntity>());
        }
        /// <summary>
        /// 指定分类的 10 最新商品
        /// </summary>
        [HttpPost]
        public ActionResult ProductNewest([DefaultValue(0)]int id) {
            int pageCount;
            return View(_productPreView.Search(new ProductSearchCondition() {
                ClassifyId = id,
                PageSize = 10,
                SortIndex = ProductSortFieldNames.SaleDateTime,
                SortDescription = SortDescriptions.DESC,
                ProductStatus = ProductStatus.Normal,
                Status = ProductSearchActionType.Sale,
                IsActive = true
            }, out pageCount));
        }
        /// <summary>
        /// 指定分类的 10 产品销售排行
        /// </summary>
        [HttpPost]
        public ActionResult ProductClassifyRank([DefaultValue(0)]int id) {
            int pageCount;
            return View("ProductRank", _productPreView.Search(new ProductSearchCondition() {
                ClassifyId = id,
                PageSize = 10,
                SortIndex = ProductSortFieldNames.SaleCount,
                SortDescription = SortDescriptions.DESC,
                ProductStatus = ProductStatus.Normal,
                Status = ProductSearchActionType.Sale,
                IsActive = true
            }, out pageCount));
        }
        /// <summary>
        /// 指定品牌的 10 产品销售排行
        /// </summary>
        [HttpPost]
        public ActionResult ProductBrandRank([DefaultValue(0)]int id) {
            int pageCount;
            return View("ProductRank", _productPreView.Search(new ProductSearchCondition() {
                BrandId = id == 0 ? -1 : id,
                PageSize = 10,
                SortIndex = ProductSortFieldNames.SaleCount,
                SortDescription = SortDescriptions.DESC,
                ProductStatus = ProductStatus.Normal,
                Status = ProductSearchActionType.Sale,
                IsActive = true
            }, out pageCount));
        }
        /// <summary>
        /// 指定产品的 10 产品同价位销售排行
        /// </summary>
        [HttpPost]
        public ActionResult ProductPriceRank([DefaultValue(0)]int id) {
            ProductPartEntity ppe =
                _productPreView.SameProduct(id, ShopB2C.Enums.ProductPart.SamePrice)
                    ?? new ProductPartEntity();
            return View("ProductRank", ppe.ProductList ?? new List<ProductEntity>());
        }
        /// <summary>
        /// 购买历史记录
        /// </summary>
        public ActionResult SaleHisotry(int productId = 0) {
            List<UserEntity> history = _orderAccess.SaleHistoryList(productId);
            return Json(history, JsonRequestBehavior.AllowGet);
        }

        #endregion
    }

    #region 历史记录attribute

    /// <summary>
    /// 历史记录attribute
    /// </summary>
    public class HistoryAttriubte : ActionFilterAttribute {

        private string _cookieName;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="cookieName">cookieName</param>
        public HistoryAttriubte(string cookieName) {
            this._cookieName = cookieName;
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext) {
            base.OnActionExecuted(filterContext);
            if (filterContext.Controller.ViewData.Model != null) {
                ProductViewModel model = (ProductViewModel)filterContext.Controller.ViewData.Model;
                string historyCookie = filterContext.HttpContext.Request.Cookies[_cookieName] != null
                    ? filterContext.HttpContext.Request.Cookies[_cookieName].Value
                    : string.Empty;
                Dictionary<string, DateTime> history = new Dictionary<string, DateTime>();
                JavaScriptSerializer json = new JavaScriptSerializer();
                try {
                    Dictionary<string, DateTime> tempHistory = json.Deserialize<Dictionary<string, DateTime>>(historyCookie)
                        ?? new Dictionary<string, DateTime>();
                    tempHistory[model.ProductView.ProductId.ToString()] = DateTime.Now;
                    var c = tempHistory.OrderByDescending(i => i.Value).Select((n, i) => { if (i < 8) { history[n.Key] = n.Value; } return false; });
                    foreach (var i in c) ;
                }
                catch { }
                string cooiekHistory = json.Serialize(history);
                filterContext.HttpContext.Response.Cookies.Add(
                    new System.Web.HttpCookie(_cookieName) {
                        Value = cooiekHistory,
                        Expires = DateTime.Now.AddDays(7)
                    });

            }

        }
    }

    #endregion
}
